home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP09.ZIP / CHAP09 / PATRON / PAGE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-23  |  24KB  |  1,026 lines

  1. /*
  2.  * PAGE.CPP
  3.  * Modifications for Chapter 9
  4.  *
  5.  * Implementation of parts of the CPage class; those member functions
  6.  * dealing with mouse events are in PAGEMOUS.CPP
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "patron.h"
  19.  
  20.  
  21. /*
  22.  * CPage::CPage
  23.  * CPage::~CPage
  24.  *
  25.  * Constructor Parameters:
  26.  *  dwID            DWORD identifier for this page.
  27.  *  hWnd            HWND of the pages window (for repaints, etc).
  28.  *  pPG             LPCPages to the Pages window.
  29.  */
  30.  
  31. CPage::CPage(DWORD dwID, HWND hWnd, LPCPages pPG)
  32.     {
  33.     m_dwID     =dwID;
  34.     m_pIStorage=NULL;
  35.  
  36.     m_cOpens=0;
  37.     m_hWnd=hWnd;
  38.     m_pPG=pPG;
  39.  
  40.     m_dwIDNext      =0;
  41.     m_cTenants      =0;
  42.     m_hWndTenantList=NULL;
  43.     m_iTenantCur    =0xFFFF;    //Tenants are zero indexed.
  44.     m_pTenantCur    =NULL;
  45.  
  46.     m_uHTCode=HTNOWHERE;
  47.     m_uSizingFlags=0;
  48.     m_fTracking=FALSE;
  49.     m_hDC=NULL;
  50.     return;
  51.     }
  52.  
  53.  
  54. CPage::~CPage(void)
  55.     {
  56.     m_hWnd=NULL;
  57.     Close(FALSE);
  58.     return;
  59.     }
  60.  
  61.  
  62.  
  63. /*
  64.  * CPage::GetID
  65.  *
  66.  * Return Value:
  67.  *  DWORD           dwID field in this page.  This function is only here
  68.  *                  to avoid hiding inline implementations in pages.h
  69.  */
  70.  
  71. DWORD CPage::GetID(void)
  72.     {
  73.     return m_dwID;
  74.     }
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. /*
  82.  * CPage::FOpen
  83.  *
  84.  * Purpose:
  85.  *  Retrieves the IStorage associated with this page.  The IStorage is
  86.  *  owned by the page and thus the page always holds a reference count.
  87.  *  The caller should call ::Close or delete this page to match this open.
  88.  *
  89.  *  This function may be called multiple times resulting in additional
  90.  *  reference counts on the storage each of which must be matched with
  91.  *  a call to ::Close.  The last ::Close can be done through delete.
  92.  *
  93.  * Parameters:
  94.  *  pIStorage       LPSTORAGE in which this page lives.
  95.  *
  96.  * Return Value:
  97.  *  BOOL            TRUE if opening succeeds, FALSE otherwise.
  98.  */
  99.  
  100. BOOL CPage::FOpen(LPSTORAGE pIStorage)
  101.     {
  102.     HRESULT         hr=NOERROR;
  103.     LPSTREAM        pIStream;
  104.     DWORD           dwMode;
  105.     char            szTemp[32];
  106.     BOOL            fNew;
  107.     BOOL            fCreated=FALSE;
  108.     TENANTLIST      tl;
  109.     LPTENANTINFO    pti;
  110.     ULONG           cb;
  111.     LPMALLOC        pIMalloc;
  112.     UINT            i;
  113.     LPTENANT        pTenant;
  114.  
  115.     fNew=(NULL==m_pIStorage);
  116.  
  117.     if (!fNew)
  118.         {
  119.         m_cOpens++;
  120.         m_pIStorage->AddRef();
  121.         return TRUE;
  122.         }
  123.  
  124.     if (NULL==pIStorage)
  125.         return FALSE;
  126.  
  127.     /*
  128.      * Attempt to open the storage under this ID.  If there is none, then
  129.      * create it.  In either case we end up with an IStorage that we
  130.      * either save in pPage or release.
  131.      */
  132.  
  133.     GetStorageName(szTemp);
  134.     dwMode=STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  135.  
  136.     hr=pIStorage->OpenStorage(szTemp, NULL, dwMode, NULL, 0, &m_pIStorage);
  137.  
  138.     if (FAILED(hr))
  139.         {
  140.         hr=pIStorage->CreateStorage(szTemp, dwMode, 0, 0, &m_pIStorage);
  141.         fCreated=TRUE;
  142.         }
  143.  
  144.     if (FAILED(hr))
  145.         return FALSE;
  146.  
  147.     m_cOpens++;
  148.  
  149.     if (NULL==m_hWndTenantList)
  150.         {
  151.         /*
  152.          * The first time we open this page, create the hidden listbox
  153.          * we'll use to track tenants.  We give it the owner-draw style
  154.          * so we can just store pointers in it.
  155.          */
  156.         m_hWndTenantList=CreateWindow("listbox", "Tenant List"
  157.             , WS_POPUP | LBS_OWNERDRAWFIXED, 0, 0, 100, 100
  158.             , HWND_DESKTOP, NULL, m_pPG->m_hInst, NULL);
  159.  
  160.         if (NULL==m_hWndTenantList)
  161.             return FALSE;
  162.         }
  163.  
  164.  
  165.     //If this is brand-new, we're done.
  166.     if (fCreated)
  167.         return TRUE;
  168.  
  169.  
  170.     /*
  171.      * Now open the stream we saved in ::Close and load all the
  172.      * tenants listed in there.  If there are none, then we don't
  173.      * have to load squat.
  174.      */
  175.  
  176.     hr=m_pIStorage->OpenStream(SZSTREAMTENANTLIST, NULL, STGM_DIRECT
  177.         | STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  178.  
  179.     if (FAILED(hr))
  180.         return FALSE;
  181.  
  182.     if (SUCCEEDED(CoGetMalloc(MEMCTX_SHARED, &pIMalloc)))
  183.         {
  184.         pIStream->Read((LPVOID)&tl, sizeof(tl), NULL);
  185.         m_cTenants=tl.cTenants;
  186.         m_dwIDNext=tl.dwIDNext;
  187.         m_iTenantCur=0;
  188.  
  189.         cb=tl.cTenants*sizeof(TENANTINFO);
  190.  
  191.         if (0!=cb)
  192.             {
  193.             pti=(LPTENANTINFO)pIMalloc->Alloc(cb);
  194.  
  195.             if (NULL!=pti)
  196.                 {
  197.                 pIStream->Read((LPVOID)pti, cb, NULL);
  198.  
  199.                 for (i=0; i < m_cTenants; i++)
  200.                     {
  201.                     if (FTenantAdd(-1, (pti+i)->dwID, &pTenant))
  202.                         pTenant->FLoad(m_pIStorage, &(pti+i)->fe, &(pti+i)->rcl);
  203.                     }
  204.  
  205.                 pIMalloc->Free((LPVOID)pti);
  206.                 }
  207.             }
  208.  
  209.         pIMalloc->Release();
  210.         }
  211.  
  212.     pIStream->Release();
  213.  
  214.     //Get and select the first tenant
  215.     if (FTenantGet(0, &m_pTenantCur, FALSE))
  216.         m_pTenantCur->Select(TRUE);
  217.  
  218.     return TRUE;
  219.     }
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /*
  226.  * CPage::Close
  227.  *
  228.  * Purpose:
  229.  *  Possibly commits the storage, then releases it reversing the
  230.  *  reference count from FOpen.
  231.  *
  232.  * Parameters:
  233.  *  fCommit         BOOL indicating if we're to commit.
  234.  *
  235.  * Return Value:
  236.  *  None
  237.  */
  238.  
  239. void CPage::Close(BOOL fCommit)
  240.     {
  241.     if (NULL==m_pIStorage)
  242.         return;
  243.  
  244.     if (fCommit)
  245.         Update();
  246.  
  247.     m_pIStorage->Release();
  248.  
  249.     //If this was the last close, make all tenants loaded->passive
  250.     if (0==--m_cOpens)
  251.         {
  252.         UINT        i;
  253.         LPTENANT    pTenant;
  254.  
  255.         m_pIStorage=NULL;
  256.  
  257.         for (i=0; i < m_cTenants; i++)
  258.             {
  259.             if (FTenantGet(i, &pTenant, FALSE))
  260.                 {
  261.                 if (NULL!=m_hWnd)
  262.                     {
  263.                     //FOpen may select again, so this repaints.
  264.                     pTenant->Select(FALSE);
  265.                     }
  266.  
  267.                 pTenant->Close(FALSE);
  268.                 //CHAPTER9MOD
  269.                 pTenant->Release();
  270.                 //End CHAPTER9MOD
  271.                 }
  272.             }
  273.  
  274.         DestroyWindow(m_hWndTenantList);
  275.         m_hWndTenantList=NULL;
  276.         }
  277.  
  278.     return;
  279.     }
  280.  
  281.  
  282.  
  283.  
  284. /*
  285.  * CPage::Update
  286.  *
  287.  * Purpose:
  288.  *  Forces a common on the page if it's open.
  289.  *
  290.  * Parameters:
  291.  *  None
  292.  *
  293.  * Return Value:
  294.  *  BOOL            TRUE if there are any open objects on this page,
  295.  *                  that is, we should remain open.
  296.  */
  297.  
  298. BOOL CPage::Update(void)
  299.     {
  300.     BOOL            fOpen=FALSE;
  301.     UINT            i;
  302.     LPTENANT        pTenant;
  303.     HRESULT         hr;
  304.     LPSTREAM        pIStream;
  305.     TENANTLIST      tl;
  306.     LPTENANTINFO    pti;
  307.     ULONG           cb;
  308.     LPMALLOC        pIMalloc;
  309.  
  310.     //Walk the list of objects and update them all as well.
  311.     for (i=0; i < m_cTenants; i++)
  312.         {
  313.         if (FTenantGet(i, &pTenant, FALSE))
  314.             fOpen |= pTenant->Update();
  315.         }
  316.  
  317.     //Now write our own stream containing the tenant list.
  318.     hr=m_pIStorage->CreateStream(SZSTREAMTENANTLIST, STGM_CREATE | STGM_WRITE
  319.         | STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, 0, &pIStream);
  320.  
  321.     if (FAILED(hr))
  322.         return fOpen;
  323.  
  324.     if (SUCCEEDED(CoGetMalloc(MEMCTX_SHARED, &pIMalloc)))
  325.         {
  326.         tl.cTenants=m_cTenants;
  327.         tl.dwIDNext=m_dwIDNext;
  328.  
  329.         pIStream->Write((LPVOID)&tl, sizeof(TENANTLIST), &cb);
  330.  
  331.         cb=m_cTenants*sizeof(TENANTINFO);
  332.         pti=(LPTENANTINFO)pIMalloc->Alloc(cb);
  333.  
  334.         if (NULL!=pti)
  335.             {
  336.             for (i=0; i < m_cTenants; i++)
  337.                 {
  338.                 FTenantGet(i, &pTenant, FALSE);
  339.                 (pti+i)->dwID=pTenant->GetID();
  340.                 pTenant->RectGet(&(pti+i)->rcl, FALSE);
  341.                 pTenant->FormatEtcGet(&(pti+i)->fe, FALSE);
  342.                 }
  343.  
  344.